package com.dnr.arch.kernel.services.persistence;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceUnit;

import com.dnr.arch.kernel.Application;
import com.dnr.arch.kernel.KernelConstants;
import com.dnr.arch.kernel.KernelFactory;
import com.dnr.arch.kernel.api.InterfaceToPersistence;
import com.dnr.arch.kernel.api.drivers.DriverInterface;
import com.dnr.arch.kernel.api.model.Value;
import com.dnr.arch.kernel.api.rules.Rule;
import com.dnr.arch.kernel.services.persistence.exceptions.PersistenceException;
import com.dnr.arch.kernel.services.rules.exceptions.RuleException;

public class JPAPersistenceDriver implements InterfaceToPersistence {

	public static JPAPersistenceDriver instance = null;

	@PersistenceContext(unitName = "DataSource")
	EntityManager em;

	public static void initialize() {
		instance = getInstance();
	}

	private JPAPersistenceDriver() {
		init();
	}

	public static JPAPersistenceDriver getInstance() {
		if (instance == null) {
			instance = new JPAPersistenceDriver();
		}
		return instance;
	}

	@Override
	public Collection<Value> findAll(Class<? extends Value> clazz) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Collection<Value> executeQuery(String query) {
		// TODO Auto-generated method stub
		return em.createQuery(query).getResultList();
	}

	@Override
	public void init() {
		if (em == null & Application.getEnv().equals(KernelConstants.LOCAL_ENV)) {
			EntityManagerFactory emf = Persistence
					.createEntityManagerFactory("DataSource");
			em = emf.createEntityManager();
		}
	}

	@Override
	public void synchronize(Value value) throws PersistenceException {
		try {
			Value oldValue = em.find(value.getClass(), value.getCode());
			for (Iterator<Rule> it = value.getRules().iterator(); it.hasNext();) {
				it.next().checkRule(oldValue, value);
			}
			em.persist(value);
		} catch (RuleException e) {
			e.printStackTrace();
		}

	}

	@Override
	public void synchronizeAndCommit(Value value) throws PersistenceException {
		em.persist(value);
	}



	@Override
	public Collection<Value> find(Class<? extends Value> clazz, Object code) {
		Collection<Value> result = new ArrayList<Value>();
		Object o = em.find(clazz, code);
		result.add((Value)o);
		return result;
	}

}
